rust 学习笔记
July 14, 2020
声明与可变性
在 rust 中声明和 javascript 有些类似, 基本可以总结为:
- 使用 let 声明变量, 使用 const 声明常量.
- 使用 mut 显式声明对变量可变性.
- 变量可重复声明, 后声明的变量覆盖前声明的变量. 重复定义的变量类型可不同.
- 常量除了具有不可变性外, 还是编译时完全确定的, 具体来说, 常量体现在内存中就是就是值固定的.
- mut 只定义了可变性, 但是变量的类型是不变的, 一旦推断类型就是不变的.
基本类型
rust 的基本类型有 4 中, 分别是整型, 浮点, 布尔和字符.
整型
整型分为有符号整型: i8, i16, i32, i64, i128, isize(取决于操作系统)
无符号整型: u8, u16, u32, u64, u128, usize(取决于操作系统)
如果不给定类型, 则首选推断类型为 i32
// 各进制写法
98_222 // decimal
0xff // hex
0o77 // octal
0b1111_0000 //binary
b'A' // byte 仅限u8
浮点
仅有 f32, f64
布尔
仅有 bool
字符
仅有 char, 大小为 4bytes
复合类型
复合类型原生有元组和数组
元组
形如(type1, type2, type3)的类型.
操作:
// 解构
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup;
// 访问
let x = tup.1;
let y = tup.2;
let z = tup.3;
数组
数组一旦声明, 长度就固定, 声明形如[type; length]
// 声明
let a: [i32; 5] = [1, 2, 3, 4, 5];
// 访问
let first = a[0];
let end = a[4];
// 初始化
let a = [3; 5];
函数
在 rust 中, 一个函数的定义如下
fn function_name(param1: type1, ...) -> [returnType] {
...
}
在 rust 中, 要理解返回值, 必须理解好语句和表达式, 表达式有返回值的, 而语句则没有返回值.
在 rust 中, 函数的返回值, 是由最后一个表达式的值决定的. 函数的定义是语句, 不返回任何值, 但是函数的调用则是表达式, 是可以返回值的, 这一定是必须要分清楚. 在这种严格的定义下可知, rsut 的赋值语句不返回任何值, 而 rsut 的代码块则是表达式, 所以在 rust 中会出现使用代码块来返回值的情况. 而控制流(if, loop, while, for)也被定义为表达式.
let a: u32 = { 4 }; // 代码块的返回值为最后一个表达式的值.
let a: u32 = if a == 3 { 3 } else if a == 4 { 4 };
let result = loop {
counter += 1;
if counter == 10 {
break couter * 2;
}
};
println!("The result is {}", result);
这种严格区分表达式和语句的理念可以有效理解 rust 在各种情况下的行为, 减少出错. 另语句必须使用分号作为结束.
所有权, 转移, 引用及借用
变量作用域: 当变量进入作用域时, 它是有效的, 并持续到离开作用域.
所有权是指一个变量拥有改变一个分配在堆上的数据的权力, 并且每时每刻, 当且仅有一个变量拥有改变同一份数据的能力.
所有权可以转移, 引用, 借用
// 转移, 所有权从s转移到s2上
let s = String::from("hello");
let s2 = s;
// 引用
let s = String::from("hello");
let s2 = &s;
// 借用, 借用是引用的一个特例, 特指将获取的引用作为函数参数
fn main() {
let s = String::from("hello");
change(&mut s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
而引用又分为可变引用和不可变引用, 可变引用可以改变数据, 但是不可变不能改变数据, 用 mut 指示.
在同一作用域下, 同一份数据的要么存在多个不可变引用, 要么存在单个可变引用
引用必须总是有效的,
这个模型旨在解决以往编程语言的几个重要问题:
- 一个变量如何释放分配的内存, rust 的答案是在离开作用域后就释放.
- 在多线程下, 如何避免数据竞争, rust 的答案是所有权机制是一个自然的读写锁模型, 可以有效避免竞争.
- 野指针, 野引用, rust 在编译阶段就不允许引用到不存在的数据.